<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Unicode的世界 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/unicode-normalization.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/unicode-normalization.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/unicode-normalization.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/unicode-normalization.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="languages.html">处理人类语言</a></span>
»
<span class="breadcrumb-link"><a href="token-normalization.html">归一化词元</a></span>
»
<span class="breadcrumb-node">Unicode的世界</span>
</div>
<div class="navheader">
<span class="prev">
<a href="asciifolding-token-filter.html">« 如果有口音</a>
</span>
<span class="next">
<a href="case-folding.html">Unicode 大小写折叠 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="unicode-normalization"></a>Unicode的世界<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/220_Token_normalization/30_Unicode_world.asciidoc">edit</a>
</h2>
</div></div></div>
<p>当Elasticsearch在比较词元(token)的时候，它是进行字节(byte)级别的比较。 换句话说，如果两个词元(token)被判定为相同的话，他们必须是相同的字节(byte)组成的。然而，Unicode允许你用不同的字节来写相同的字符。</p>
<p>例如， <em>é</em> 和 <em>é</em> 的不同是什么？这取决于你问谁。对于Elasticsearch，第一个是由 <code class="literal">0xC3 0xA9</code> 这两个字节组成的，第二个是由 <code class="literal">0x65
0xCC 0x81</code> 这三个字节组成的。</p>
<p>对于Unicode，他们的差异和他们的怎么组成没有关系，所以他们是相同的。第一个是单个单词 <code class="literal">é</code> ，第二个是一个简单 <code class="literal">e</code> 和重音符 <code class="literal">´</code>。</p>
<p>如果你的数据有多个来源，就会有可能发生这种状况：因为相同的单词使用了不同的编码，导致一个形式的 <code class="literal">déjà</code> 不能和它的其他形式进行匹配。</p>
<p>幸运的是，这里就有解决办法。这里有4种Unicode <em>归一化形式</em> (<em>normalization forms</em>) : <code class="literal">nfc</code>, <code class="literal">nfd</code>, <code class="literal">nfkc</code>, <code class="literal">nfkd</code>，它们都把Unicode字符转换成对应标准格式，把所有的字符 进行字节(byte)级别的比较。</p>
<div class="sidebar">
<div class="titlepage"><div><div>
<p class="title"><strong>Unicode归一化形式 (Normalization Forms)</strong></p>
</div></div></div>
<pre class="literallayout">_组合_ (_composed_) 模式—`nfc` 和 `nfkc`—用尽可能少的字节(byte)来代表字符。 ((("composed forms (Unicode normalization)"))) 所以用 `é` 来代表单个字母 `é` 。  _分解_ （_decomposed_） 模式—`nfd` and `nfkd`—用字符的每一部分来代表字符。所以 `é` 分解为 `e` 和 `´`。 ((("decomposed forms (Unicode normalization)")))</pre>

<p><em>规范</em> (<em>canonical</em>) 模式—<code class="literal">nfc</code> 和 <code class="literal">nfd</code>&amp;—把连字作为单个字符，例如 <code class="literal">ﬃ</code> 或者 <code class="literal">œ</code> 。 <em>兼容</em> (<em>compatibility</em>) 模式—<code class="literal">nfkc</code> 和
<code class="literal">nfkd</code>—将这些组合的字符分解成简单字符的等价物，例如： <code class="literal">f</code> + <code class="literal">f</code> + <code class="literal">i</code> 或者 <code class="literal">o</code> + <code class="literal">e</code>.</p>
</div>
<p>无论你选择哪一个归一化(normalization)模式，只要你的文本只用一种模式，那你的同一个词元(token)就会由相同的字节(byte)组成。例如，<em>兼容</em> (<em>compatibility</em>) 模式  可以用连词 <code class="literal">ﬃ</code> 的简化形式 `ffi`来进行对比。</p>
<p>你可以使用 <code class="literal">icu_normalizer</code> 语汇单元过滤器(token filters)  来保证你的所有词元(token)是相同模式：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "nfkc_normalizer": { <a id="CO143-1"></a><i class="conum" data-value="1"></i>
          "type": "icu_normalizer",
          "name": "nfkc"
        }
      },
      "analyzer": {
        "my_normalizer": {
          "tokenizer": "icu_tokenizer",
          "filter":  [ "nfkc_normalizer" ]
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO143-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>用 <code class="literal">nfkc</code> 归一化(normalization)模式来归一化(Normalize)所有词元(token).</p>
</td>
</tr>
</table>
</div>
<div class="tip admon">
<div class="icon"></div>
<div class="admon_content">
<p>包括刚才提到过的 <code class="literal">icu_normalizer</code> 语汇单元过滤器(token filters)在内，这里还有 <code class="literal">icu_normalizer</code>  <em>字符</em> 过滤器(<em>character</em> filters)。虽然它和语汇单元过滤器做相同的工作，但是会在文本到达过滤器之前做。到底是用`standard` 过滤器，还是 <code class="literal">icu_tokenizer</code> 过滤器，其实并不重要。因为过滤器知道怎么来正确处理所有的模式。</p>
<p>但是，如果你使用不同的分词器，例如： <code class="literal">ngram</code>, <code class="literal">edge_ngram</code>, 或者 <code class="literal">pattern</code> 分词器，那么在语汇单元过滤器(token filters)之前使用 <code class="literal">icu_normalizer</code>  字符过滤器就变得有意义了。</p>
</div>
</div>
<p>通常来说，你不仅仅想要归一化(normalize)词元(token)的字节(byte)规则，还需要把他们转成小写字母。这个可以通过 <code class="literal">icu_normalizer</code> 和定制的归一化(normalization)的模式 <code class="literal">nfkc_cf</code> 来实现。下一节我们会具体讲这个。</p>
</div>
<div class="navfooter">
<span class="prev">
<a href="asciifolding-token-filter.html">« 如果有口音</a>
</span>
<span class="next">
<a href="case-folding.html">Unicode 大小写折叠 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>